'''This file defines a generic pointer, which may get data from mouse or a
joystick. It also defines an event type POINTER_CLICK, from which you may
fetch position and button, as well as the pointer's type and name.

Drawing the cursor of the pointer is the programmer's responsibility.'''

from pygame import event, joystick, mouse
from pygame.locals import *

POINTER_CLICK          = USEREVENT
DEFAULT_JOYSTICK_SPEED = 8

def post_click(p_type, name, pos, button):
    '''Posts a POINTER_CLICK event. The event stores the pointer's type and id,
    and the click's position and button'''
    event.post(event.Event(POINTER_CLICK, {"id":name, "type":p_type, "pos":pos,
                                           "button":button}))

class Pointer:
    '''This class represents a pointer. It is able to return information about
    the cursor's position and to post POINTER_CLICK events whenever update() is
    called.'''

    def __init__(self, p_type, name):
        '''A pointer device always needs to have a type and an id.'''
        self.p_type = p_type
        self.name = name

    def get_pos(self):
        '''Returns the pointer's position.'''
        pass

    def set_pos(self, pos):
        '''Sets the pointer's position.'''

    def update(self, events):
        '''Update's the pointer's position (if needed) and posts any events
        that may be interpreted as clicks.'''
        pass


class MousePointer(Pointer):
    '''This class encapsulates the mouse as a pointer. This class has little or
    no value in one's project unless one plans to use different types of
    pointers at the same time.'''

    def __init__(self, name):
        Pointer.__init__(self, "mouse", name)

    def get_pos(self):
        return mouse.get_pos()

    def set_pos(self, pos):
        mouse.set_pos(pos)

    def update(self, events):
        for e in [e for e in events if e.type == MOUSEBUTTONDOWN]:
            post_click(self.p_type, self.name, e.pos, e.button)

class JoystickPointer(Pointer):
    '''This class defines a Joystick as a pointer. You may set a joystick's
    responsiveness to motion during init or with set_speed.'''

    def __init__(self, name, joy, speed=DEFAULT_JOYSTICK_SPEED):
        '''In addition to the name, the joystick pointer's init function
        receives the Joystick object which it is supposed to represent, and
        may receive a responsivity parameter "speed".'''
        Pointer.__init__(self, "joystick", name)
        self.joy   = joy
        self.pos   = (0, 0)
        self.speed = speed

    def get_pos(self):
        return self.pos

    def set_constraints(self, area):
        self.contraints = rect.Rect(area)

    def set_pos(self, pos):
        self.pos = pos

    def set_speed(self):
        self.speed = speed

    def update(self, events):
        self.pos = (self.pos[0] + self.joy.get_axis(0)*self.speed,
                    self.pos[1] + self.joy.get_axis(1)*self.speed)
        for e in [e for e in events if e.type == JOYBUTTONDOWN]:
            if e.joy == self.joy.get_id():
                post_click(self.p_type, self.name, self.pos, e.button)

